package com.le.tester.imooc.oldimmortal.coding.buffer;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Future;

/**
 * createTime：2025-05-15 14:31
 * description：buffer example
 */
public class BufferExample {


    @Test
    public void gen() throws IOException {
        Random random = new Random();
        String fileName = "word.txt";

//        4k
        int bufferSize = 4 * 1024;
        BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(fileName), bufferSize);
        long start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++) {
            for (int j = 0; j < 5; j++) {
                fout.write(97 + random.nextInt(5));
            }
        }

        fout.close();
        System.out.println(System.currentTimeMillis() - start);
    }

    @Test
    public void readTestWithBuffer() throws IOException {
        String fileName = "word.txt";
        int bufferSize = 4 * 1024;
        BufferedInputStream fin = new BufferedInputStream(new FileInputStream(fileName), bufferSize);
        long start = System.currentTimeMillis();
        byte[] bytes = new byte[1024 * 4];
        while ((fin.read(bytes)) != -1) {
        }

        long end = System.currentTimeMillis();
        fin.close();
        System.out.println((end - start));
    }

    @Test
    public void readTestNIO() throws IOException {
        String fileName = "word.txt";

        FileChannel channel = new FileInputStream(fileName).getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024 * 8);
        long start = System.currentTimeMillis();
        while ((channel.read(buffer)) != -1) {
            //每次读完
//            position set 0,limit set default
            buffer.flip();


            buffer.clear();
        }

        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    public void readTestAsync() throws IOException {
        String fileName = "word.txt";

        long start = System.currentTimeMillis();
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(Paths.get(fileName), StandardOpenOption.READ);
        ByteBuffer buffer = ByteBuffer.allocate(1024 * 8);
        Future<Integer> future = fileChannel.read(buffer, 0);
        buffer.flip();
        buffer.clear();
        System.out.println(System.currentTimeMillis() - start);
    }

    @Test
    public void testChinese() {
        String chinese = "载营魄抱一①，能无离乎？专气致柔②，能如婴儿乎③？涤除玄鉴④，能无疵乎？爱民治国，能无为乎⑤？" +
                "天门开阖⑥，能为雌乎⑦？明白四达，能无知乎⑧？生之畜之⑨，生而不有，为而不恃，长而不宰，是谓玄德⑩。";


//        编码中文
        byte[] bytes1 = StandardCharsets.UTF_8.encode(chinese).array();
//        随机复制
        byte[] bytes2 = Arrays.copyOfRange(bytes1, 0, 21);

//        使用buffer,cap==20
        ByteBuffer byteBuffer = ByteBuffer.allocate(22);
        CharBuffer charBuffer = CharBuffer.allocate(22);

//        20<21
        byteBuffer.put(bytes2);
        byteBuffer.flip();
        System.out.println("bBuf is " + byteBuffer);

//        把byteBuffer中的内容放进charsetBuffer,才是中文
        StandardCharsets.UTF_8.newDecoder().decode(byteBuffer, charBuffer, true);
        charBuffer.flip();
        System.out.println("cBuf is " + charBuffer);

        if (charBuffer.hasRemaining()) {
            char[] chars = new char[charBuffer.length()];
            charBuffer.get(chars);
            System.out.println("here:" + Arrays.toString(chars));
        }

        System.out.format("limit-pos=%d\n", byteBuffer.limit() - byteBuffer.position());
        if (byteBuffer.limit() - byteBuffer.position() > 0) {
//            还有存在未读取的charset
            Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
        }
    }
}
